package net.bithappens.hnqe.impl.querymanager;

import java.util.Collection;
import java.util.Set;

import net.bithappens.hnqe.InvalidInstanceException;
import net.bithappens.hnqe.InvalidQueryException;
import net.bithappens.hnqe.cache.ICacheQuery;
import net.bithappens.hnqe.mapper.IMapper;
import net.bithappens.hnqe.mapper.IMapperPool;
import net.bithappens.hnqe.query.IQuery;
import net.bithappens.hnqe.query.Instance;
import net.bithappens.hnqe.query.QueryTree;

import org.apache.log4j.Logger;

public class QueryManager implements IQuery{

	private Logger log = Logger.getLogger(this.getClass());
	
	private ICacheQuery cache;
	
	private IMapperPool mapperPool;
	
	
	public QueryManager(ICacheQuery cache, IMapperPool mapperPool) throws Exception{
		
		this.cache = cache;
		
		this.mapperPool = mapperPool;
		
	}
	
	@Override
	public Set<Instance> queryGraph(String instanceId, int instanceCount, QueryTree query) throws InvalidQueryException, InvalidInstanceException {
	
		Set<Instance> result = cache.queryCache(instanceId, query);
		
		log.info("query returned "+result.size()+" instance matches");
		
		if(result == null || result.size() == 0 || (instanceCount > 0 && result.size() < instanceCount)){
			
			log.info("start lazy load");
			
			Collection<IMapper> listToTrigger = mapperPool.getAllMapper(instanceId);

			LazyLoadHandler loadHandler = new LazyLoadHandler();
			if(loadHandler.triggerLazyLoad(instanceId, listToTrigger, query)) {
				
				log.info("Execute query again");
				
				result = cache.queryCache(instanceId, query);	
				
			}
		} 
		return result;
	}
}
